package com.heima.app.gateway.filters;

import com.heima.app.gateway.utils.Jwtutil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 全局过滤器
 */
@Component
public class MyFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /*
        TODO：验证登录请求
        1. 任何请求过来以后，首先先经过微服务的网关
        2. 判断该请求是否为登录请求，如果是登录请求，则放行
        3. 不是登录请求，则需要校验token
           - 判断token是否存在    不存在返回401错误（权限不足，前端会自动跳转到登录页面）
           - 判断token是否有效（是否过期），无效返回401错误（权限不足，前端会自动跳转到登录页面）
           - 如果token都是正常的，则路由到具体的微服务进行数据访问
         */
        // 1 获取请求体、响应体
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 2 获取请求路径（uri）
        String uri = request.getURI().getPath();
        /*
        request. getRequestURI() 返回值类似：/ServletTest/servlet/Hello
        request. getRequestURL() 返回值类似： http://localhost:8080/ServletTest/servlet/Hello
         */
        // 3 登录请求，放行
        if (uri.contains("/login_auth")) {
            return chain.filter(exchange);
        }
        // 3.1 验证token(token在请求头中)
        String token = request.getHeaders().getFirst("token");
        boolean verify = Jwtutil.verify(token);
        if (verify) {
            return chain.filter(exchange);
        }
        // 4 非登录请求，拦截
        // 4.1 设置状态码
        response.setStatusCode(HttpStatus.UNAUTHORIZED);  //401
        // 4.2 设置数据类型  json
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON); //JSON类型
        // 4.3 设置提示信息
        return response.writeWith(Flux.just(response.bufferFactory().wrap("请登录！".getBytes()))); //提示信息
    }
}